package tjo;

import static org.junit.Assert.assertTrue;
import org.junit.Test;

/**
 * This test verifies that the Meteor.whichWallOrCorner method correctly identifies when a given set
 * of x and y coordinates are near a wall or corner, and if so how far they are.
 * 
 * @author Jordan Takayama
 * @since October 10, 2011
 */
public class TestMethodDistanceToWallOrCorner {
  /**
   * Instantiate a copy of the class containing the method to be tested.
   */
  public tjo.Meteor testRobot = new tjo.Meteor();

  /**
   * The maximum possible x-coordinate on a sample 800 by 600 pixel battlefield.
   */
  private static final double MAX_WIDTH = 800.0;

  /**
   * The maximum possible y-coordinate on a sample 800 by 600 pixel battlefield.
   */
  private static final double MAX_HEIGHT = 600.0;

  /**
   * Represents the origin coordinates (x and y) of any Robocode battlefield.
   */
  private static final double ORIGIN = 0.0;

  /**
   * Defines the "danger zone" (in pixels) around the walls which determines if the robot is near a
   * wall or corner.
   */
  private static double outerBound = 200.0;

  /**
   * Checks that distanceToWallOrCorner is using a distance function which returns standard results.
   */
  @Test
  public void test() {
    // Create and initialize boolean variables for testing.
    boolean nearNothing, nearEast, nearSouth, nearWest, nearNorth, nearSouthWest, nearSouthEast, 
    nearNorthEast, nearNorthWest;
    nearNothing = false;
    nearEast = false;
    nearSouth = false;
    nearWest = false;
    nearNorth = false;
    nearSouthWest = false;
    nearSouthEast = false;
    nearNorthEast = false;
    nearNorthWest = false;
    
    // Check test cases.
    if (testRobot.distanceToWallOrCorner(ORIGIN, MAX_WIDTH, MAX_HEIGHT, 300.0, 250.0, outerBound) 
        == -1.0) {
      nearNothing = true;
    }
    if (testRobot.distanceToWallOrCorner(ORIGIN, MAX_WIDTH, MAX_HEIGHT, 170.0, 215.0, outerBound) 
        == 170.0) {
      nearEast = true;
    }
    if (testRobot.distanceToWallOrCorner(ORIGIN, MAX_WIDTH, MAX_HEIGHT, 357.0, 200.0, outerBound) 
        == 200.0) {
      nearSouth = true;
    }
    if (testRobot.distanceToWallOrCorner(ORIGIN, MAX_WIDTH, MAX_HEIGHT, 770.0, 320.5, outerBound) 
        == 30.0) {
      nearWest = true;
    }
    if (testRobot.distanceToWallOrCorner(ORIGIN, MAX_WIDTH, MAX_HEIGHT, 300.0, 540.0, outerBound) 
        == 60.0) {
      nearNorth = true;
    }
    if (testRobot.distanceToWallOrCorner(ORIGIN, MAX_WIDTH, MAX_HEIGHT, 40.1, 30.0, outerBound) 
        == 50.080035942479114) {
      nearSouthWest = true;
    }
    if (testRobot.distanceToWallOrCorner(ORIGIN, MAX_WIDTH, MAX_HEIGHT, 640.0, 120.3, outerBound) 
        == 200.18014387046483) {
      nearSouthEast = true;
    }
    if (testRobot.distanceToWallOrCorner(ORIGIN, MAX_WIDTH, MAX_HEIGHT, 650.0, 530.0, outerBound) 
        == 165.5294535724685) {
      nearNorthEast = true;
    }
    if (testRobot.distanceToWallOrCorner(ORIGIN, MAX_WIDTH, MAX_HEIGHT, 42.0, 582.0, outerBound) 
        == 45.69463863518345) {
      nearNorthWest = true;
    }
    
    // Check results of test cases.
    assertTrue("Check case not near any wall or corner: ", nearNothing);
    assertTrue("Check case near east wall: ", nearEast);
    assertTrue("Check case near south wall: ", nearSouth);
    assertTrue("Check case near west wall: ", nearWest);
    assertTrue("Check case near north wall: ", nearNorth);
    assertTrue("Check case near south-west corner: ", nearSouthWest);
    assertTrue("Check case near south-east corner: ", nearSouthEast);
    assertTrue("Check case near north-east corner: ", nearNorthEast);
    assertTrue("Check case near north-west corner: ", nearNorthWest);
  }
}
